﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using xKnight.Attacking.EncodedXss;
using xKnight.Attacking.SimpleXss;
using xKnight.Attacking.Xss;
using xKnight.Data;
using xKnight.Models;

namespace xKnight.Attacking
{
    internal abstract class AttackerAgent
    {
        internal delegate void AttackAsyncCaller();

        #region Field

        protected AttackingSharedReource _attackingSharedResource;

        #endregion

        #region Events

        public delegate void AgentAttackStartedEventHandler(object sender, EventArgs e);

        /// <summary>
        /// This event will rise just before the agent get started.
        /// Inheritors should not rise this event
        /// </summary>
        public event AgentAttackStartedEventHandler AgentAttackStarted;

        public delegate void AgentAttackCompletedEventHander(object sender, EventArgs e);

        /// <summary>
        /// This event will rise just after the agent done his job
        /// Inheritors should not rise this event
        /// </summary>
        public event AgentAttackCompletedEventHander AgentAttackCompleted;

        public delegate void AgentAttackAnnouncedEventHandler(object sender, AttackAnnouncedEventArgs e);

        /// <summary>
        /// This event will rise to report about agent inner status
        /// </summary>      
        public event AgentAttackAnnouncedEventHandler AgentAttackAnnounced;

        #endregion

        #region Constructor

        public AttackerAgent(AttackingSharedReource attackingSharedResource)
        {
            _attackingSharedResource = attackingSharedResource;
        }

        #endregion

        #region Interface

        internal abstract void Attack();

        /// <summary>
        /// Make async call to Attack()
        /// </summary>
        public void AttackAsync()
        {
            AttackAsyncCaller asyncCaller = new AttackAsyncCaller(Attack);

            OnAgentAttackStarted();
            asyncCaller.BeginInvoke(new AsyncCallback(OnAgentAttackCompleted), null);
        }

        #endregion

        #region Event Handlers

        private void OnAgentAttackStarted()
        {
            if (AgentAttackStarted != null)
                AgentAttackStarted(this, new EventArgs());
        }

        private void OnAgentAttackCompleted(IAsyncResult result)
        {
            OnAgentAttackCompleted();
        }

        private void OnAgentAttackCompleted()
        {
            if (AgentAttackCompleted != null)
                AgentAttackCompleted(this, new EventArgs());
        }

        protected void OnAgentAttackAnnounced(AttackAnnounceItem announceItem)
        {
            if (AgentAttackAnnounced != null)
                AgentAttackAnnounced(this, new AttackAnnouncedEventArgs(announceItem));
        }

        #endregion
    }
}
